package com.cloudspace.jindun.activity.dianhua;

import android.os.Bundle;
import android.os.CountDownTimer;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Chronometer;
import android.widget.ImageView;
import android.widget.TextView;

import com.cloudspace.jindun.R;
import com.cloudspace.jindun.activity.CustomTitleBaseActivity;
import com.cloudspace.jindun.dao.PhoneRecord;
import com.cloudspace.jindun.ext.aq.AQUtility;
import com.cloudspace.jindun.log.APPLog;
import com.cloudspace.jindun.manager.ContactPersonManager;
import com.cloudspace.jindun.manager.PhoneRecordManager;
import com.cloudspace.jindun.model.Person;
import com.cloudspace.jindun.net.manager.ImageManager;
import com.cloudspace.jindun.utils.ObjUtil;
import com.cloudspace.jindun.utils.TimeUtils;
import com.cloudspace.jindun.utils.ToastMaker;
import com.linphone.LinphoneManager;

import org.linphone.core.LinphoneAddress;
import org.linphone.core.LinphoneCall;
import org.linphone.core.LinphoneChatMessage;
import org.linphone.core.LinphoneChatRoom;
import org.linphone.core.LinphoneCore;
import org.linphone.core.LinphoneCoreException;
import org.linphone.core.LinphoneCoreListenerBase;

import static com.cloudspace.jindun.R.id.incoming_answer;
import static com.cloudspace.jindun.R.id.incoming_refuse;
import static com.cloudspace.jindun.R.id.phone_ll_hangup;
import static com.cloudspace.jindun.activity.dianhua.CallInOrOut.INCALL;

/**
 * Created by zengxianhua on 16/12/24.
 */

public class IncomingCallActivity extends CustomTitleBaseActivity implements View.OnClickListener{
    public String sipAddress = null;

    private ImageView head;
    private TextView name;
    private TextView phoneNumber;
    private TextView companyName;

    private TextView state;
    private Chronometer timer;

    private View callingView;
    private View incomingCallView;
    private Button hangupBtn;

    private Button incomingAnswerBtn;
    private Button incomingRefuseBtn;
    private Person callingPerson;
    private boolean callSuccess = false;

    private View stopCallView;

    private CountDownTimer countTimer;

    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_incomingcall, false);

        LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
        if (lc != null) {
            lc.addListener(mListener);
        }


        initView();
        handleInComingCall();
    }
    
    private void answerIncomingCall() {
        try {
            acceptCallUpdate(true);
        } catch (Exception e) {
            APPLog.d("zxh", Log.getStackTraceString(e));
        }

    }
    private void handleInComingCall() {
        try {
            LinphoneCall call = LinphoneManager.getLc().getCurrentCall();
            displayCurrentCall(call);
        } catch (Exception e) {
            APPLog.e("zxh", Log.getStackTraceString(e));
        }

    }

    private void initView() {
        head = (ImageView) findViewById(R.id.phone_iv_head);
        name  = (TextView) findViewById(R.id.phone_tv_name);
        phoneNumber = (TextView) findViewById(R.id.phone_tv_tele);
        companyName = (TextView) findViewById(R.id.phone_tv_remarkName);
        state = (TextView) findViewById(R.id.phone_tv_callState);
        state.setText(getString(R.string.call_in));
        timer = (Chronometer) findViewById(R.id.chronometer);
        timer.setVisibility(View.GONE);
        callingView = findViewById(R.id.calling);
        callingView.setVisibility(View.GONE);
        hangupBtn = (Button) findViewById(phone_ll_hangup);
        hangupBtn.setOnClickListener(this);

        incomingCallView = findViewById(R.id.incoming_call);
        incomingAnswerBtn = (Button) findViewById(R.id.incoming_answer);
        incomingRefuseBtn = (Button) findViewById(R.id.incoming_refuse);

        incomingCallView.setVisibility(View.VISIBLE);
        incomingRefuseBtn.setOnClickListener(this);
        incomingAnswerBtn.setOnClickListener(this);
    }

    private void showCallerInfo(LinphoneAddress address) {
        if (ObjUtil.isEmpty(address)){
            return;
        }

        sipAddress = address.asStringUriOnly();

        if (TextUtils.isEmpty(sipAddress)){
            return;
        }

        sipAddress = sipAddress.replace("sip:", "");
        APPLog.d("zxh", "incoming call sip address:" + sipAddress);

        callingPerson = ContactPersonManager.getInstance().queryBySipAccount(sipAddress);
        if (callingPerson != null) {
            ImageManager.loadCircleImage(this, head, callingPerson.getImageUrl());
            name.setText(callingPerson.getName());
            phoneNumber.setText(callingPerson.getPhoneNumber());
            companyName.setText(callingPerson.getCompany());
        }else{
            head.setBackgroundResource(R.drawable.avatar);
            name.setText(getResources().getString(R.string.unknown));
            phoneNumber.setText(getResources().getString(R.string.unknown));
            companyName.setText(getResources().getString(R.string.unknown));
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
        if (lc != null) {
            lc.removeListener(mListener);
        }
    }

    private void addARecord() {
        if (callingPerson == null){
            APPLog.d("zxh", "callingPerson == null");
            return;
        }

        PhoneRecord record = new PhoneRecord();
        record.setUserid(String.valueOf(callingPerson.getUserId()));
        record.setImage(callingPerson.getImageUrl());
        if (callSuccess){
            record.setCallfrom(INCALL);
        }else{
            record.setCallfrom(CallInOrOut.CALLFAIL);
        }

        String timeStr = TimeUtils.getNowTimeString();
        record.setDaystr(timeStr.split(" ")[0]);

        String hmStr = timeStr.split(" ")[1];
        record.setTime(timeStr);

        record.setTimestamp(System.currentTimeMillis());

        record.setHm(hmStr.substring(0, hmStr.lastIndexOf(":")));
        record.setName(callingPerson.getName());

        PhoneRecordManager.getInstance().addPhoneRecord(record);
    }

    private void showBusy() {
        //对方忙
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                state.setText(getResources().getString(R.string.call_busy));
            }
        });
    }

    public void calling() {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                timer.setVisibility(View.VISIBLE);
                timer.start();
                callSuccess = true;
                state.setText(getResources().getString(R.string.call_online));
                showCallingView();
            }
        });

    }

    private void displayCurrentCall(LinphoneCall call){
        LinphoneAddress lAddress = call.getRemoteAddress();
        if (lAddress != null){
            showIncomingCallView(lAddress);
        }
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case phone_ll_hangup:
                hangout(true);
                break;

            case incoming_answer:
                answerIncomingCall();
                break;

            case incoming_refuse:
                refuse();
                break;
            default:
                break;
        }
    }

    private void hangout(boolean isMe) {
        showCompleteView(isMe);
        hangUpCall();
    }

    private void refuse() {
        acceptCallUpdate(false);
        showCompleteView(true);
    }

    //通话结束界面
    //自己挂断，isMe为true
    private void showCompleteView(final boolean isMe) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (timer != null){
                    timer.setVisibility(View.GONE);
                }

                callingView.setVisibility(View.GONE);
                incomingCallView.setVisibility(View.GONE);

                if (isMe){
                    if (state != null){
                        state.setText(getString(R.string.hang_out));
                        state.setTextColor(getResources().getColor(R.color.red_1));
                    }
                }else{
                    if (state != null){
                        state.setText(getString(R.string.other_hang_out));
                        state.setTextColor(getResources().getColor(R.color.red_1));
                    }
                }
            }
        });

        AQUtility.postDelayed(new Runnable() {
            @Override
            public void run() {
                finish();
            }
        }, 500);
    }

    //来电界面
    private void showIncomingCallView(LinphoneAddress address) {
        incomingCallView.setVisibility(View.VISIBLE);
        callingView.setVisibility(View.GONE);

        state.setText(getResources().getString(R.string.ringing));
        showCallerInfo(address);
        addARecord();
    }

    private void showCallingView(){
        incomingCallView.setVisibility(View.GONE);
        callingView.setVisibility(View.VISIBLE);
    }

    private final static int SECONDS_BEFORE_HIDING_CONTROLS = 4000;
    private final static int SECONDS_BEFORE_DENYING_CALL_UPDATE = 30000;

    private LinphoneCoreListenerBase mListener = new LinphoneCoreListenerBase() {
        @Override
        public void messageReceived(LinphoneCore lc, LinphoneChatRoom cr, LinphoneChatMessage message) {
            APPLog.zxhLog("messageReceived:" + message);
        }

        @Override
        public void callState(LinphoneCore lc, final LinphoneCall call, LinphoneCall.State state, String message) {
            APPLog.zxhLog("callState:" + message);
            if (LinphoneManager.getLc().getCallsNb() == 0) {
                finish();
                return;
            }

            if (state == LinphoneCall.State.IncomingReceived) {
                APPLog.zxhLog("callState: IncomingReceived");
            } else if (state == LinphoneCall.State.Paused || state == LinphoneCall.State.PausedByRemote ||  state == LinphoneCall.State.Pausing) {
                APPLog.zxhLog("callState: Paused");
            } else if (state == LinphoneCall.State.Resuming) {
                APPLog.zxhLog("callState: Resuming");
            } else if (state == LinphoneCall.State.StreamsRunning) {
                APPLog.zxhLog("callState: StreamsRunning");
                showCallingView();
            } else if (state == LinphoneCall.State.CallUpdatedByRemote) {
                APPLog.zxhLog("callState: CallUpdatedByRemote");
                showCallingView();
            }
        }

        @Override
        public void callEncryptionChanged(LinphoneCore lc, final LinphoneCall call, boolean encrypted, String authenticationToken) {
        }

    };


    private void hangUpCall() {
        LinphoneCore lc = LinphoneManager.getLc();
        LinphoneCall currentCall = lc.getCurrentCall();

        if (currentCall != null) {
            lc.terminateCall(currentCall);
        } else if (lc.isInConference()) {
            lc.terminateConference();
        } else {
            lc.terminateAllCalls();
        }
    }

    public void acceptCallUpdate(boolean accept) {
        if (countTimer != null) {
            countTimer.cancel();
        }

        LinphoneCall call = LinphoneManager.getLc().getCurrentCall();
        if (call == null) {
            return;
        }

        if (!accept) {
            hangout(true);
            return;
        }

        try {
            LinphoneManager.getLc().acceptCall(call);
            calling();
        } catch (LinphoneCoreException e) {
            ToastMaker.showToastLong(e.getMessage());
            APPLog.e(e);
        }
    }
}
